//Copyright (c) 2006-2007 Microsoft Corporation.  All rights reserved
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;

namespace InvocationFramework.Common.Library
{
    /// <summary>
    /// Helper para serializar objetos en formato binario
    /// </summary>
    internal static class BinarySerializerHelper
    {
        #region Public Methods

		/// <summary>
		/// Serialize an objeto or graph to a byte array.
		/// </summary>
		/// <remarks>
		///  For more information see:
		///  http://msdn.microsoft.com/msdnmag/issues/02/04/net/print.asp
		///  
		///  Remember to add the attribute [Serializable] to all objects/classes to serialize and
		///  the attribute [NonSerialized] to those objects that must not be serialized.
		/// </remarks>
		/// <param name="objGraph">Object to serialize</param>
		/// <returns>Serialized bytes</returns>
        public static byte[] SerializeToBytes( object objGraph )
        {
            return SerializeToMemory( objGraph, false ).ToArray( );
        }

		/// <summary>
		/// Serialize an objet or graph to a MemoryStream.
		/// </summary>
		/// <remarks>
		/// For more information see:
		/// http://msdn.microsoft.com/msdnmag/issues/02/04/net/print.asp
		/// http://msdn.microsoft.com/msdnmag/issues/02/07/net/print.asp
		///  
		/// Remember to add the attribute [Serializable] to all objects/classes to serialize and
		/// the attribute [NonSerialized] to those objects that must not be serialized.
		/// </remarks>
		/// <param name="objGraph">Object to serialize</param>
		/// <param name="deep">True for child objects serialization</param>
		/// <returns>Serialized MemoryStream</returns>
        public static MemoryStream SerializeToMemory( object objGraph, bool deep )
        {
            //Construct a stream that is to hold the serialized objects
            MemoryStream stream = new MemoryStream( );
            //Construct a serialization formatter that does all the hard work
            BinaryFormatter formatter = new BinaryFormatter( );

            if ( deep )
                //This line is explained in the "Streaming Contexts" section
                formatter.Context = new StreamingContext( StreamingContextStates.Clone );

            //Tell the formatter to serialize the objects into the stream
            formatter.Serialize( stream, objGraph );

            //Reset Position.
            if ( stream.CanSeek )
                stream.Position = 0;

            //Return the stream of serialized objects back to the caller
            return stream;
        }

		/// <summary>
		/// Deserialize an objeto or graph from a byte array.
		/// </summary>
		/// <remarks>
		/// For more information see:
		/// http://msdn.microsoft.com/msdnmag/issues/02/04/net/print.asp
		///  
		/// Remember to add the attribute [Serializable] to all objects/classes to serialize and
		/// the attribute [NonSerialized] to those objects that must not be serialized.
		/// </remarks>
		/// <param name="input">Object to deserialize</param>
		/// <returns>Deserialized object</returns>
        public static object DeserializeFromBytes( byte[] input )
        {
            using ( MemoryStream memStream = new MemoryStream( input ) )
            {
                return DeserializeFromStream( memStream, null, false );
            }
        }

        /// <summary>
        /// Deserialize an objeto or graph from a byte array.
        /// </summary>
        /// <remarks>
        ///  For more information see:
        ///  http://msdn.microsoft.com/msdnmag/issues/02/04/net/print.asp
        ///  
        ///  Remember to add the attribute [Serializable] to all objects/classes to serialize and
        ///  the attribute [NonSerialized] to those objects that must not be serialized.
        /// </remarks>
        /// <param name="input">Object to deserialize</param>
        /// <param name="objBinder"></param>
        /// <returns>Deserialized object</returns>
        public static object DeserializeFromBytes( byte[] input, SerializationBinder objBinder )
        {
            using ( MemoryStream memStream = new MemoryStream( input ) )
            {
                return DeserializeFromStream( memStream, objBinder, false );
            }
        }

        /// <summary>
        /// Deserialize an objeto or graph from a MemoryStream.
        /// </summary>
        /// <remarks>
        /// For more information see:
        /// http://msdn.microsoft.com/msdnmag/issues/02/04/net/print.asp
        ///  
        /// Remember to add the attribute [Serializable] to all objects/classes to serialize and
        /// the attribute [NonSerialized] to those objects that must not be serialized.
        /// </remarks>
        /// <param name="stream">Object to deserialize</param>
        /// <param name="objBinder"></param>
        /// <param name="deep">True for child objects serialization</param>
        /// <returns>Deserialized object</returns>
        public static object DeserializeFromStream( Stream stream, SerializationBinder objBinder, bool deep )
        {
            //Construct a serialization formatter that does all the hard work
            BinaryFormatter formatter = new BinaryFormatter( );

            if ( deep )
                formatter.Context = new StreamingContext( StreamingContextStates.Clone );

            if ( objBinder != null )
                formatter.Binder = objBinder;

            //Tell the formatter to deserialize the objects from the stream
            return formatter.Deserialize( stream );
        } 

        #endregion
    }
}